From c7320df0c906d927b542d6739fd4c19fe3191335 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 30 Jun 2021 04:52:35 +0200 Subject: [PATCH] gdk: Add gdk_gl_context_is_shared() ... and use it in the GL renderers. --- gdk/gdkglcontext.c | 49 +++++++++++++++++++++++++++++++++++++++ gdk/gdkglcontext.h | 3 +++ gdk/gdkglcontextprivate.h | 9 ++++--- gsk/gl/gskgldriver.c | 9 ++++--- gsk/ngl/gskngldriver.c | 11 ++++----- 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index a82c7e3bc4..6681b44648 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -333,6 +333,18 @@ gdk_gl_context_real_get_damage (GdkGLContext *context) }); } +static gboolean +gdk_gl_context_real_is_shared (GdkGLContext *self, + GdkGLContext *other) +{ + if (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self)) != gdk_draw_context_get_display (GDK_DRAW_CONTEXT (other))) + return FALSE; + + /* XXX: Should we check es or legacy here? */ + + return TRUE; +} + static void gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context, cairo_region_t *region) @@ -406,6 +418,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass) klass->realize = gdk_gl_context_real_realize; klass->get_damage = gdk_gl_context_real_get_damage; + klass->is_shared = gdk_gl_context_real_is_shared; draw_context_class->begin_frame = gdk_gl_context_real_begin_frame; draw_context_class->end_frame = gdk_gl_context_real_end_frame; @@ -812,6 +825,42 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context, priv->is_legacy = !!is_legacy; } +/** + * gdk_gl_context_is_shared: + * @self: a `GdkGLContext` + * @other: the `GdkGLContext` that should be compatible with @self + * + * Checks if the two GL contexts can share resources. + * + * When they can, the texture IDs from @other can be used in @self. This + * is particularly useful when passing `GdkGLTexture` objects between + * different contexts. + * + * Contexts created for the same display with the same properties will + * always be compatible, even if they are created for different surfaces. + * For other contexts it depends on the GL backend. + * + * Both contexts must be realized for this check to succeed. If either one + * is not, this function will return %FALSE. + * + * Returns: %TRUE if the two GL contexts are compatible. + */ +gboolean +gdk_gl_context_is_shared (GdkGLContext *self, + GdkGLContext *other) +{ + GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self); + GdkGLContextPrivate *priv_other = gdk_gl_context_get_instance_private (other); + + g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE); + g_return_val_if_fail (GDK_IS_GL_CONTEXT (other), FALSE); + + if (!priv->realized || !priv_other->realized) + return FALSE; + + return GDK_GL_CONTEXT_GET_CLASS (self)->is_shared (self, other); +} + /** * gdk_gl_context_set_use_es: * @context: a `GdkGLContext` diff --git a/gdk/gdkglcontext.h b/gdk/gdkglcontext.h index 10bac82e9b..278da869ca 100644 --- a/gdk/gdkglcontext.h +++ b/gdk/gdkglcontext.h @@ -54,6 +54,9 @@ void gdk_gl_context_get_version (GdkGLContext * int *minor); GDK_AVAILABLE_IN_ALL gboolean gdk_gl_context_is_legacy (GdkGLContext *context); +GDK_AVAILABLE_IN_4_4 +gboolean gdk_gl_context_is_shared (GdkGLContext *self, + GdkGLContext *other); GDK_AVAILABLE_IN_ALL void gdk_gl_context_set_required_version (GdkGLContext *context, diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h index 2f9fc23eed..b64a6f4510 100644 --- a/gdk/gdkglcontextprivate.h +++ b/gdk/gdkglcontextprivate.h @@ -52,10 +52,13 @@ struct _GdkGLContextClass { GdkDrawContextClass parent_class; - gboolean (* realize) (GdkGLContext *context, - GError **error); + gboolean (* realize) (GdkGLContext *context, + GError **error); - cairo_region_t * (* get_damage) (GdkGLContext *context); + cairo_region_t * (* get_damage) (GdkGLContext *context); + + gboolean (* is_shared) (GdkGLContext *self, + GdkGLContext *other); }; typedef struct { diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 621c25825c..8fe726b315 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -518,14 +518,13 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self, if (GDK_IS_GL_TEXTURE (texture)) { - GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture); - GdkGLContext *shared_context = gdk_gl_context_get_shared_context (self->gl_context); + GdkGLTexture *gl_texture = (GdkGLTexture *) texture; + GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture); - if (texture_context == self->gl_context || - (gdk_gl_context_get_shared_context (texture_context) == shared_context && shared_context != NULL)) + if (gdk_gl_context_is_shared (self->gl_context, texture_context)) { /* A GL texture from the same GL context is a simple task... */ - return gdk_gl_texture_get_id ((GdkGLTexture *)texture); + return gdk_gl_texture_get_id (gl_texture); } else { diff --git a/gsk/ngl/gskngldriver.c b/gsk/ngl/gskngldriver.c index 32862047d8..eba888f514 100644 --- a/gsk/ngl/gskngldriver.c +++ b/gsk/ngl/gskngldriver.c @@ -741,16 +741,13 @@ gsk_ngl_driver_load_texture (GskNglDriver *self, if (GDK_IS_GL_TEXTURE (texture)) { - GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture); - GdkGLContext *shared_context = gdk_gl_context_get_shared_context (context); - - if (texture_context == context || - (shared_context != NULL && - shared_context == gdk_gl_context_get_shared_context (texture_context))) + GdkGLTexture *gl_texture = (GdkGLTexture *) texture; + GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture); + if (gdk_gl_context_is_shared (context, texture_context)) { /* A GL texture from the same GL context is a simple task... */ - return gdk_gl_texture_get_id ((GdkGLTexture *)texture); + return gdk_gl_texture_get_id (gl_texture); } else { -- 2.30.2